<!DOCTYPE html><html lang="ru" dir="ltr" spellcheck><head><!--#include file="h.htm"--><meta name="description" content="Пиццикато Алексея Лота. Полезные высказывания из книги 'Надежный код' Бруно."><meta name="keywords" content="сайт алексея лота, технологии, бруно, надежный код, разработка по, алексей лот"><title>Полезные высказывания из книги "Надежный код" Бруно</title></head><body><header><h1 class=m>Пиццикато Алексея Лота</h1><nav><a href="p.htm">Главная</a><a href="m.htm">Песни</a><a href="l.htm">Психология</a><a href="r.htm">Рассказы</a><a href="b.htm">Религия</a><a href="s.htm">Стихотворения</a><a id="i" href="t.htm">Технологии</a><a href="f.htm">Философия</a><a href="i.htm">Фотография</a></nav></header><article id="c"><h2 class=m>Полезные высказывания из книги "Надежный код" Бруно</h2><div id="w">Более высокий уровень абстрагирования позволяет больше времени уделять важным элементам любого проекта.<br><br>Нет единого мнения по вопросу: что именно должны знать и уметь все разработчики.<br><br>Разработка ПО - это не инженерия.<br><br>Настройка производительности и безопасности не должна откладываться на конец проекта.<br><br>После прочтения советов необходимо выработать привычку их применения.<br><br>На практике методология водопада работает не очень хорошо, поскольку многие важные особенности программы проявляются лишь на этапе реализации.<br><br>Нереалистично тестировать ПО в конце цикла разработки.<br><br>agilealliance.org<br><br>agilemanifesto.org/principles.html<br><br>Сейчас используются Scrum (наиболее широко применяется в Microsoft), XP, TDD.<br><br>blogs.msdn.com/e7<br><br>Шаги разработки:<br>сбор сведений от заказчика, совместное обсуждение требований, детальное тестирование, описание параметров компонентов и общей архитектуры системы;<br>процедуры контроля качества кода - стандарты, совместная разработка, оптимизация, модульное тестирование;<br>обширное тестирование системы и сборки.<br><br>Методы контроля качества применять как можно раньше.<br><br>Чем больше кода написано, тем сложнее его тестировать.<br><br>Стремиться и сосредоточиться на качестве, надежности, безопасности.<br><br>Применять итеративную разработку с итерациями не более 6-8 недель, полностью завершать один компонент перед началом работы, разделять работы на несколько автономных групп, достаточно часто обмениваться информацией о состоянии проекта.<br><br>Использовать типичные методологии развертывания, оборудования и инструментов, планировать процессы, стремясь к предсказуемости и повторяемости процедур.<br><br>Для ускорения процессов создания и развертывания, упрощения обмена информацией использовать в командах общие инструменты и процедуры для управления исходным кодом, сборки, ведения баз данных, общие подходы к программированию и единую терминологию.<br><br>Отказаться от модели водопада.<br><br>Создавать проверяемые модули.<br><br>Ежедневно запускать сборку и запускать автоматические BVT-тесты.<br><br>Использовать продукты компании в её работе, начиная с самых ранних стадий их разработки.<br><br>Идентифицировать участников приложения (типы) и способы их взаимодействия друг с другом (прототипирование; концепции, взаимоотношения и взаимодействия проверяются на полноту и корректность; здесь же анализируются риски дизайн);<br><br>В приложениях на управляемом коде в качестве языка метапрограммирования, позволяющего изменять поведение приложения во время выполнения, применять XML.<br><br>Производительность с самого начала часть любого проекта.<br><br>Факторы масштабирования - часть дизайна приложения.<br><br>Безопасность закладывается в дизайне приложения.<br><br>Тестеры гарантируют полное покрытие кода тестами.<br><br>Учиться эффективно управлять памятью.<br><br>Использовать безопасное программирование.<br><br>Сердцем программирования являются этапы анализа требований и проектирования.<br><br>Цикл разработки ПО:<br>анализ требований;<br>проектирование;<br>спецификации;<br>программирование;<br>тестирование;<br>развертывание;<br>обслуживание.<br><br>Написанию кода обязательно должен предшествовать этап проектирования.<br><br>Дизайн приложения в идеале не зависит от особенностей реализации.<br><br>В ООП 40-50% времени разработчик тратит на проектирование кода.<br><br>Число написанных строк кода - неверный показатель труда.<br><br>Секрет успеха заключается в неизменности цели.<br><br>На устранение проблемы на этапе тестирования требуется в 4 раза больше времени, чем на этапе проектирования.<br><br>C# - прямой потомок C++.<br><br>Существительные из предметной области могут стать объектами, глаголы и глагольные группы - поведением.<br><br>Проектирование должно управлять реализацией, но не наоборот.<br><br>Из списка объектов предметной области удаляются не взаимодействующие с другими.<br><br>Использовать UML для моделирования в проектировании.<br><br>Типы UML схем см. в книге.<br><br>Изоляция классов друг от друга - один из принципов ООП.<br><br>В конструкторе классов VS изменения в схеме классов немедленно отражаются в коде и наоборот.<br><br>Один из способов повысить гибкость кода - писать его как можно меньше.<br><br>Метаданные хранить в xml-файлах конфигурации в корневом каталоге приложения (не использовать ini и реестр).<br><br>Использование метаданных позволяет разработчику отделить конкретные логические детали от исходного кода.<br><br>Настройки, применимые ко всем приложениям на данном компьютере, хранятся в machine.config.<br><br>Храните в метаданных настройки приложения.<br><br>Храните в метаданных данные приложения.<br><br>Управляйте поведением приложения при помощи метаданных.<br><br>Все компоненты должны при возможности управляться конфигурацией.<br><br>Изменение файлов конфигурации не требует регрессионного тестирования.<br><br>Использовать сжатие данных, передаваемых по сети.<br><br>Не использовать множество маленьких статических избражений.<br><br>Стандарт HTTP/1.1 предполагает одновременную загрузку браузером только двух ресурсов с одного имени хоста (новые браузеры игнорируют это требование).<br><br>Не злоупотреблять перенаправлением страниц.<br><br>В веб-приложении не стоит использовать много уникальных имен хостов, чтобы избежать излишних запросов DNS.<br><br>Максимально сокращать объем данных, передаваемых по сети, для оптимизации производительности.<br><br>Добивайтесь максимально эффективного использования пропускной способности сети.<br><br>Свести число HTTP-запросов к минимуму.<br><br>Используйте сжатие HTTP.<br><br>Минимизируйте объем кодов JavaScript и CSS (Yui Compressor, JsMin).<br><br>Уменьшайте палитру изображений.<br><br>Настраивайте сроки действия даных (Expires, Cache-Control, ETag).<br><br>Прочитать High Performance WebSites (Souders), mnot.net/cache_docs.<br><br>Увеличение числа параллельных TCP-портов позволит параллельно загружать больше содержимого.<br><br>HTTP/1.0 требовал создания нового соединения для каждого HTTP-запроса. Пакеты keep-alive позволяют браузерам отправлять несколько HTTP-запросов с одного соединения, что сокращает сетевой траффик за счет уменьшения числа открываемых и закрываемых соединений (заголовок Connection: keep-alive).<br><br>Запросы к DNS могут занимать до 120 мс.<br><br>Уменьшение числа обращений к DNS (рекомендуется <=4-6 уникальных имен хостов) улучшит время ответа страницы, но может негативно повлиять на параллельную загрузку содержимого.<br><br>Если у приложения мало ресурсов, в общем случае лучше обойтись одним именем хоста.<br><br>В общем случае перенаправлений лучше избегать, используя лишь при необходимости поддерживать в течение некоторого времени старый URL или создать URL с более запоминаемым адресом страницы.<br><br>Используйте сети доставки содержимого (CDN).<br><br>Внедряйте спрайты CSS - вместо загрузки одного изображения загружайте несколько параллельно (для мелких значков используйте один спрайт).<br><br>В общем случае внедрение JavaScript и CSS в страницу ускоряет прорисовку.<br><br>Размещение JavaScript и CSS во внешних файлах позволяет кешировать их браузером (при последующих обращениях внешние сценарии выгоднее).<br><br>Размещайте CSS в начале страницы (если файлы CSS расположены вне блока HEAD, браузер заблокирует прогрессивную прорисовку).<br><br>Размещайте сценарии JavaScript в конце страницы (при загрузке файлов JS браузеры блокируют загрузку любого другого содержимого, включая содержимое, идущее по параллельным TCP-портам).<br><br>Программа совершенствования производительности:<br>определить сценарии использования и приоритеты;<br>проанализировать разработки конкурентов;<br>сформулировать задачи производительности;<br>внедрять эффективные методики;<br>измерять и тестировать.<br><br>Устанавливайте ограничения производительности для ключевых сценариев (например, количество запросов get).<br><br>Непрерывно анализируйте и тестируйте производительность.<br><br>Экспериментируйте и разбирайтесь в поведении пользователя (измененная версия приложения предоставляется небольшой группе пользователей).<br><br>Упреждающе загружать страницы и сценарии, о которых известно, что пользователь будет их посещать.<br><br>Выясните, какие факторы влияют на производительность работы конечного пользователя.<br><br>Применяйте инструменты тестирования производительности.<br><br>Приложение считается масштабируемым (scalable), если его производительность возрастает по мере расширения аппаратной базы.<br><br>Необходима возможность наращивать мощность приложения за счет инфраструктуры - новых серверов, накопителей данных и сетевого оборудования (работа пользователей при этом не должна зависеть от объема нагрузки).<br><br>Приложение должно быть всегда доступно для пользователей, поэтому нужно избавлять приложение от мелких сбоев, наподобие выхода из строя жестких дисков, для чего нужно встраивать избыточность и отказоустойчивость как в дизайн веб-приложения, так и в топологию развертывания).<br><br>Чем больше оборудования и чем шире развернуто ПО, тем сложнее им управлять и обслуживать его, поэтому очень важно, чтобы разработчики приложения проектировали его таким образом, чтобы его просто было настраивать, развертывать и контролировать.<br><br>Производительность приложения необходимо проверять при различной нагрузке.<br><br>Веб-приложение можно на любом языке спроектировать так, что оно будет масштабируемым.<br><br>Разработчики должны учитывать возможность пиковых нагрузок и даже выбросов.<br><br>В дизайн приложения необходимо встроить возможность распределения нагрузки по нескольким серверам.<br><br>Масштабируемые приложения позволяют реагировать на повышение нагрузки простым добавлением нового оборудования.<br><br>Две основные стратегии масштабирования приложений при расширении аппаратной базы: вертикальное (scaling up) и горизонтальное (scaling out).<br><br>Вертикальное масштабирование состоит в добавлении ресурсов на тот же компьютер, либо в переносе приложения на более мощный компьютер (как правило, модернизация компьютера заключается в установке дополнительных процессоров, добавлении памяти или увеличении дискового пространства). Преимущество вертикального масштабирования - простота. СО временем затраты на аппаратное обеспечение могут сделать использование приложения невыгодным. Может быть такое, что не удастся найти устройство требуемой мощности. Вертикальное масштабирование удобно в тех случаях, когда целевая аудитория приложения не слишком обширна и затраты на модернизацию не превышают выгоду от использования приложения.<br><br>В горизонтальном масштабировании по мере роста запросов приложения в систему включаются новые серверы (оборудование уникальной мощности не требуется). Преиущество горизонтального масштабирования - экономичность в сравнении с вертикальным. Кластер из большого количества дешевых серверов невысокой мощности может оказаться дешевле за счет низкой стоимости оборудования и пониженного энергопотребления (однако тут востребована отказоустойчивость, так как дешевое оборудование чаще выходит из строя). Горизонтальное масштабирование посредством более дорогих и качественных компьютеров обеспечит более устойчивую и надежную работу. В крупных системах предпочтение стоит отдавать горизонтальному масштабированию. Систему с горизонтальным масштабированием проще обслуживать. Основной недостаток горизонтального масщтабирования - высокие затраты на администрирование и значительные накладные расходы, связанные с управлением десятками, сотнями и тысячами серверов (проблема решается API-интерфейсами администрирования). Горизонтальное масштабирование следует рассматривать в первую очередь для приложений со значительной целевой аудиторией и тенденцией к устойчивому росту.<br><br>В некоторых случаях горизонтального масштабирования разработчики сталкиваются со специфическими требованиями к дизайну, которые не поддаются линейному масштабированию.<br><br>При масштабировании уровня БД веб-приложения к вашим услугам вертикальное и горизонтальное масштабирования.<br><br>В MSSQL масштабирование выполняется созданием федерации и секционированием.<br><br>Выбирайте простую архитектуру, чтобы будущее расширение приложения не привело к недопустимым затратам на его обслуживание.<br><br>Выбирайте дизайн, пригодный для горизонтального масштабирования.<br><br>Используйте устройства для балансировки нагрузки (серверы можно добавлять и удалять в процессе работы).<br><br>Правильный выбор аппаратного обеспечения практически всегда связан с использованием однотипного оборудования на всех серверах определенного типа. Стандартизация оборудования не только экономит средства за счет оптовых закупок, но также снижает затраты на диагностику и обслуживание.<br><br>При сбое в ключевом компоненте приложение должно продолжать работу в сокращенном объеме (приложение должно быть отказоустойчивым).<br><br>Отказоустойчивость следует применять только к более важным компонентам.<br><br>На разработчике лежит ответственность за своевременное информирование руководства о важности создания отказоустойчивой инфраструктуры и о возможных вариантах её создания.<br><br>Приложение должно проектироваться таким образом, чтобы минимизировать влияние зависимостей.<br><br>Сужение функциональности лучше, чем сообщение об ошибке.<br><br>Приложения должны быть просты в эксплуатации (приложение должно обладать управляемостью и сопровождаемостью).<br><br>Данные инструментирования может собирать отдельная служба.<br><br>Ведите активный мониторинг приложения.<br><br>Выделите ключевые метрики и цели мониторинга.<br><br>Планируйте стратегию роста и стратегию реакции на сбои.<br><br>Масштабирование "по ролям": отдельные функциональные области масштабируются независимо друг от друга.<br><br>В каждом компоненте приложения предусматривайте аварийный выход.<br><br>Автоматизируйте основные задачи управления.<br><br>Составляйте план восстановления системы.<br><br>Постоянно оценивайте загруженность инфратсруктуры и планируйте её развитие.<br><br>"Writing secure code" Ховард<br><br>"Threat modeling" Свидерски<br><br>Используйте механизмы проверки подлинности и авторизации .NET (Windows Identity, Windows Principle, Generic Identity, Generic Principle).<br><br>Шифруйте конфиденциальные данные.<br><br>Считайте внешние приложения небезопасными по умолчанию.<br><br>Реализуйте безопасную обработку отказов.<br><br>Реализуйте безопасную обработку ошибок и исключений.<br><br>Приложения следует проектировать так, чтобы они могли выполняться с наименьшими возможными полномочиями (Anti-Cross Site Scripting Library).<br><br>Включайте в конфигурацию по умолчанию только необходимые компоненты.<br><br>По умолчанию приложение должно работать с ограниченными полномочиями.<br><br>Организуйте процесс сопровождения приложения и устранения ошибок (устранение сбоев и сбор отзывов).<br><br>Предоставьте пользователям руководство по установке и настройке.<br><br>Соблюдайте требования законодательства.<br><br>Организуйте диалог с пользователями по вопросам безопасности.<br><br>Разработайте план реагирования на проблемы с безопасностью.<br><br>".NET Security Programming" Маршал<br><br>Элементы политики безопсасности времени выполнения:<br><br>В .NET поддерживаются пользовательские разрешения и наборы разрешений.<br><br>Свидетельство источника предоставляется хостом, запрашивающим выполнение сборки.<br><br>Кодовая группа связывает свидетельство с набором разрешений.<br><br>Уровни политики определяют границы предоставляемых разрешений.<br><br>.NET Framework Configuration Tool<br>Code Access Security Policy Tool<br>Permissions View Tool<br>Build Verification Testing<br>Final Security Review<br>Intrusion Detection Systems<br>FxCop<br><br>В динамическом коде память выделяется динамическим объектам по требованию при помощи оператора new.<br><br>Модель управления памятью в .NET опирается на два основных допущения: большие объекты живут долго и друг с другом чаще всего взаимодействуют объекты близкого размера.<br><br>Управляемая куча делится на поколения и кучу больших объектов. Поколения 0, 1 и 2 используются для группировки объектов по размеру и времени жизни. 2 - самое старое поколение с самыми большими объектами. 0,1 - эфемерные поколения. Большими считаются объекты более 85000 байт. Большие объекты хранятся в куче больших объектов. Задача сборщика мусора - освободить память. Сборку мусора запускают события:<br>- После очередного выделения памяти в случае его успешного завершения превышен порог для поколения 0. Новые объекты всегда помещаются в поколение 0. В поколении 0 всегда находятся самые молодые объекты.<br>- В куче больших объектов не хватает памяти.<br>- Вызван метод GC.Collect.<br>Сборщик мусора собирает сначала 0 поколение, затем 1 и 2. Если обрабатывается какое-либо поколение, обязательо обрабатывается и младшее. Для объектов, оставшихся после сборки, сборщик повышает поколение. При сборке мусора объекты в обрабатываемых поколениях признаются недоступными. Дерево памяти при сборке мусора перестраивается. Объекты, не попавшие в дерево, считаются недостижимыми и готовыми к сборке. Сборщик мусора сжимает доступные объекты в управляемой куче. Использовать метод GC.Collect не рекомендуется, так как он способен помешать работе сборщика мусора в штатном режиме. Управляемый класс - это интерфейс между управляемым приложением и неуправляемыми ресурсами. Сборщик мусора будет искать в памяти только управляемый интерфейсный класс, не учитывая память для неуправляемого ресурса (GC.AddMemoryPressure и GC.RemoveMemmoryPressure). Вызовите метод GC.AddMemoryPressure в конструкторе управляемого класса, чтобы применить нагрузку, равную памяти неуправляемого ресурса. В методе Finalize или Dispose вызовите GC.RemoveMemoryPressure.<br><br>Сборщик обрабатывает кучу больших объектов (LOH) при полной сборке мусора. Память в куче больших объектов не сжимается. Для крупных объектов лучше создавать буфер - это позволяет выделять для больших объектов смежные блоки памяти (вы экономите память, минимизируете фрагментацию и сокращаете количество полных (наиболее ресурсоемких) сборок мусора). При помощи Finalize() не стоит очищать управляемые объекты. Уничтожение объектов с дескриптором требует 2 цикла сборки мусора. В отличие от Finalize(), метод IDisposable.Dispose детерминирован, вызывается вручную и выполняется без задержки. В методе Dispose можно ссылаться как на упрвляемые, так и на неуправляемые ресурсы. Библиотека .NET автоматически вызывает Dispose, если реализован IDisposable.<br><br>Упаковки приводят к дополнительным сборкам мусора.<br><br>Используйте метода Finalize только при крайней необходимости.<br><br>Для отладки управляемой кучи использовать CLR Profiler. <br><br>Присваивание объекту значения null делает объект недостижимым.<br>Пишите код с учетом того, что произвойти можеьт все что угодно. Язык C# спроектирован с учетом требований упреждающего программирования - стиля кодирования, направленногго на решение возможных проблем до того, как они возникнут.<br><br>Всегда задавайте максимальный уровень предупреждений компилятора.<br><br>В новых приложениях обрабатывайте предупреждения как ошибки.<br><br>Выполняйте совместный анализ кода при добавлении кода в систему управления версиями и при развертывании продукта. Тестирование разделяется на верификацию и валидацию. Лучше рассматривать покрытие кода как косвенное подтверждение надежности приложения. Покрытие функций - выполняется ли конкретная функция и если да, то как часто. Покрытие операторов - выполнялась ли строка кода и если да, то как часто. Покрытие путей - выполнялась ли определенная ветвь кода. Уровень покрытия кода должен быть определен прежде, чем начнется программирование, согласован и доведен до всех участников команды. Если исходный код не удовлетворяет заданному стандарту, его нельзя передавать в систему управления версиями. Комментируйте все и всегда. Комментарии должны почти надоедать. Код не должен содержать трюков. /// - комментарий документации.<br><br>В начале функции проверяйте корректость переданных в нее параметров.<br><br>По возможности решайте проблемы с помощью обработки ошибок, а не исключений.<br><br>По возможности функции должны возвращать значения, отличные от void.<br><br>Всегда проверяйте значение, возвращаемое функцией.<br><br>Не пишите небезопасный код.<br><br>Не перехватывайте "избранные" исключения.<br><br>Избегайте определения или использования объектных типов (boxing и downcasting снижают производительность).<br><br>Всегда используйте общие (generic) коллекции вместо стандартных.<br><br>По возможности вместо коллекций используйте массивы.<br><br>Не используйте собственные API приложения для реализации функциональности, имеющейся в .NET Framework Class Library (FCL).<br><br>Из всех операторов циклов отдавайте предпочтение циклу for (дисциплинирует).<br><br>Присваивайте неиспользуемым объектам null.<br><br>Если у вас есть выбор, всегда используйте блок вместо одиночного выражения.<br><br>Разбивайте сложное выражение на простые подвыражения.<br><br>Придерживайтесь рекомендаций CLS.<br><br>Проверяйте на overflow и underflow с помощью MinValue, MaxValue.<br><br>Избегайте ненужной рекурсии.<br><br>microsoft.com/patterns<br>Шаблоны проектирования представляют собой известные и проверенные решения типовых задач программирования. В плане разработки выделять время на отладку. Разработчики оперируют разрабатываемой версией, а клиенты получают рабочую версию. Основная причина возникновения проблем с ПО - недостаток образования.<br>watin.sourceforge.net<br><br>Многопотоковые приложения тестировать на разном количестве ядер.<br><br>ADPlus<br><br>Отладочные версии приложений не оптимизируются.<br><br>В отладочной версии веб-приложения не истекает срок действия запросов ASP.NET.<br><br>Для отладочных версий веб-приложений не предусмотрена пакетная компиляция.<br><br>Большое количество сборок приводит к фрагментации виртуальной памяти.<br><br>В отладочной версии веб-приложения клиентские библиотеки кода и статические изображения из файла webresources.axd не кешируются.<br><br>ILDASM/ILASM, Reflector, Son of Strike (SOS), Windbg, GFlags.<br><br>Трассировка=инструментирование.<br><br>Первичное исключение не выбрасывается, а передается на обработку приложению, в отличие от вторичного.<br><br>Перехват необрабатываемых ошибок на уровне страницы более приоритетен, чем их перехват на уровне приложения.<br></div></article><br><footer>&copy;&nbsp;<i>Copyright&nbsp;<a href="https://алексейлот.рф">алексейлот.рф</a>&nbsp;-&nbsp;возьми главную ноту</i></footer></body></html>
